package demo1;

import java.util.HashMap;
import java.util.HashSet;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 石方旭
 * Date: 2022-06-28
 * Time: 17:18
 */
public class TestKM {


//    public static int test(int[] arr, int k, int m) {
//        HashMap<Integer, Integer> map = new HashMap<>();
//        for (int num : arr) {
//            if (map.containsKey(num)) {
//                map.put(num, map.get(num) + 1);
//            } else {
//                map.put(num, 1);
//            }
//        }
//        int ans = 0;
//        for (int num : map.keySet()) {
//            if (map.get(num) == k) {
//                ans = num;
//                break;
//            }
//        }
//        return ans;
//    }

    public static int test(int[] arr,int k,int m){
        HashMap<Integer,Integer> map = new HashMap<>();
        //一种数出现了k次  多种数字出现了m次
        for(int num:arr){
            if(map.containsKey(num)){
                map.put(num,map.get(num)+1);
            }else {
                map.put(num,1);
            }
        }
        int ans = 0;
        for (int num : map.keySet()) {
            if (map.get(num) == k) {
                ans = num;
                break;
            }
        }
        return ans;
    }

    public static int onlyKTimes(int[] array,int k,int m){
        //对于每一个数字，我们都将其二进制加到同一个数组中
        int[] tmp = new int[32];
        for(int num:array){
            for(int i =0;i<32;++i){
                tmp[i] += ((num>>i)&1);
            }
        }
        //如果二进制的某一位%m!=0就证明这个位置上 我们要找的这个数字在这个位置上有1
        int ans =0;
        for(int i =0;i<32;++i){
            if((tmp[i]%m)!=0){
                ans |= (1<<i);
            }
        }
        return ans;
    }
    //产生【-range ~ +range】之间的随机数
    public static int rangeNumber(int range){
        return ((int)(Math.random()*range)+1)-((int)(Math.random()*range)+1);
    }
    //产生一个随机数组
    public static int[] randomArray(int maxKinds,int range,int k,int m){
        int randomNum = rangeNumber(range);//产生【-range ~ +range】之间的随机数
        int randomKinds = (int)(Math.random()*maxKinds)+2;//至少要产生2个以上种数
        int index =0;
        int[] array = new int[k+(randomKinds-1)*m];
        //先将k次数放进去
        for(;index<k;index++){
            array[index] = randomNum;
        }
        //在放入m次数字
        randomKinds--;
        HashSet<Integer> set = new HashSet<>();
        set.add(randomNum);//先将这个k次的数字放进set避免m次数字与它重复
        while(randomKinds!=0){
            int currNum = 0;
            do{
                currNum = rangeNumber(range);
            }while(set.contains(currNum));//每一次放进去的数字不能重复
            set.add(currNum);
            randomKinds--;
            //将m次出现的数字放进array里面去
            for(int i =0;i<m;++i){
                array[index++] = currNum;
            }
        }
        //让其数组里面的数字更加随机
        for(int i =0;i<array.length;++i){
            int j = (int)(Math.random()* array.length);//产生0-n-1之间的数字
            int tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
        }
        return array;
    }

    public static void main(String[] args) {
        int textTimes = 10000;//测试次数
        int kinds = 7;//一共有7种数字
        int range = 100;//我们要将产生的数字控制在【-range ~ +range】
        int max = 9;//产生的数字不能超过9
        System.out.println("开始测试");
        for(int i =0;i<textTimes;++i){
            int a = (int)(Math.random()*max)+1;//产生的数字在1-9之间
            int b = (int)(Math.random()*max)+1;//产生的数字在1-9之间
            int k = Math.min(a,b);
            int m = Math.max(a,b);
            if(k==m){
                m++;
            }
            //产生一个随机数组
            int[] arr = randomArray(kinds,range,k,m);
            int ans1 = test(arr,k,m);
            int ans2 = onlyKTimes(arr,k,m);
            if(ans1!=ans2){
                System.out.println("出错了");
            }
        }
        System.out.println("测试结束");
    }

}
